home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1996 September / MACPOWER-1996-09.ISO.7z / MACPOWER-1996-09.ISO / 第2特集:プラグイン大集合 / PIC2 Save / p2loadhi.c < prev    next >
Text File  |  1995-01-16  |  8KB  |  476 lines

  1. /*
  2.  *    PIC2 高速フォーマットの展開 by やなぎさわ
  3.  */
  4.  
  5.  
  6. #include "pic2.h"
  7.  
  8. /* ----- 各種変数(p2構造体の中を直接使わないのは、昔作ったのを直すのがめんどうなのと
  9.          微妙に型が違うのでキャストの嵐になっていまうからです ----- */
  10.  
  11. static uchar *fbufp;
  12. static long n_fbuf;
  13. static ushort bit_buf;
  14. static short n_bit_buf;
  15. static long cache8_pos;
  16. static long len;
  17. static long len2;
  18. static P2 *p2;
  19. static pix *vram_prev;
  20. static pix *vram_now;
  21. static pix *vram_next;
  22. static schar *flag_now;
  23. static schar *flag_next;
  24. static pix (_HUGE_ *cache)[N_CACHE];
  25. static ushort *cache_pos;
  26. static short ynow;
  27.  
  28. static pix (*read_color)( pix bc);
  29.  
  30. /* エラー時の脱出用 */
  31. static jmp_buf jmp_env;
  32.  
  33. /*
  34.  * 指定したビットするだけファイルから読み込む 
  35.  */
  36. static ulong        /* 読んだ値 */
  37. bit_load(
  38.     long size        /* ビット長 */
  39.     )
  40. {
  41.     ulong    a = 0;
  42.     
  43.     /* 8bitづつバッファリングするので */
  44.     bit_buf &= 0xff;
  45.  
  46.     /* 残りのビット数より指定ビット数が大きい場合 */
  47.     while ( size > n_bit_buf) {
  48.         /* ビットバッファの残りを8ビット超にもってくる */
  49.         bit_buf = bit_buf << n_bit_buf;
  50.         /* のこりビットを一気に入れるのでその分あける */
  51.         a = a << n_bit_buf;
  52.         /* のこりは8ビット超にあるので、それを8つ右シフトして、それ自身を入れる */
  53.         a = a + ( bit_buf >> 8);
  54.         /* 読み込みサイズ更新 */
  55.         size -= n_bit_buf;
  56.  
  57.         /* バッファにデータがなければ次のデータをバッファに読み込む */
  58.         if ( n_fbuf == 0) {
  59.             fbufp = p2->fbuf;
  60.             n_fbuf = read_file2( p2, fbufp, N_FBUF);
  61.             if ( n_fbuf == 0) {
  62.                 p2errno = p2->errno = P2E_FEOF;
  63.                 longjmp( jmp_env, 1);
  64.             }
  65.         }
  66.  
  67.         /* ビットバッファを更新 */
  68.         --n_fbuf;
  69.         bit_buf = *fbufp++;
  70.         n_bit_buf = 8;
  71.     }
  72.     /* データにsizeビット入れるので、その分あける */
  73.     a = a << size;
  74.     /* そのデータを8ビット超にもってきて */
  75.     bit_buf = bit_buf << size;
  76.     /* それを入れる */
  77.     a = a + ( bit_buf >> 8);
  78.     n_bit_buf -= size;
  79.     return ( a);
  80. }
  81.  
  82. /*
  83.  * 長さデータを読み込む
  84.  */
  85. static long                /* 長さ */
  86. read_len( void)
  87. {
  88.     long a;
  89.     
  90.     a = 0;
  91.     while (bit_load( 1)) {
  92.         a++;
  93.     }
  94.     if ( a == 0) return ( 0);
  95.     return ( bit_load( a) + (1 << a) - 1);
  96. }
  97.  
  98. /*
  99.  * 連鎖を展開
  100.  */
  101. static void
  102. expand_chain( long x, pix cc)
  103. {
  104.     if ( bit_load(1) != 0) {
  105.         if ( bit_load(1) != 0) { /* 下 */
  106.             vram_next[ x] = cc;
  107.             flag_next[ x] = -1;
  108.  
  109.         } else if ( bit_load(1) != 0) {
  110.             if ( bit_load(1) == 0) { /* 左2下 */
  111.                 vram_next[ x - 2] = cc;
  112.                 flag_next[ x - 2] = -1;
  113.  
  114.             } else {    /* 左1下 */
  115.                 vram_next[ x - 1] = cc;
  116.                 flag_next[ x - 1] = -1;
  117.  
  118.             }
  119.         } else {
  120.             if ( bit_load(1) == 0) { /* 右2下 */
  121.                 vram_next[ x + 2] = cc;
  122.                 flag_next[ x + 2] = -1;
  123.  
  124.             } else {        /* 左1下 */
  125.                 vram_next[ x + 1] = cc;
  126.                 flag_next[ x + 1] = -1;
  127.  
  128.             }
  129.         }
  130.     }
  131. }
  132.  
  133. /*
  134.  * 24bit色のよみこみ
  135.  */
  136. static pix
  137. read_color24( pix bc)
  138. {
  139.     pix    cc;
  140.     long    j,k,m;
  141.  
  142.     k = bc >> 16;
  143.  
  144.     if ( bit_load( 1) == 0) {
  145.         cache_pos[k] = m = (cache_pos[k] - 1) & (N_CACHE - 1);
  146.         cc = cache[k][m] = bit_load( 24);
  147.     } else {
  148.         j = bit_load( 6);    /* 6= log2(n_cache) */
  149.         m = cache_pos[k];
  150.         cc = cache[k][(m + j) & (N_CACHE - 1)];
  151.     }
  152.     return ( cc);
  153. }
  154.  
  155. /*
  156.  * 15bit色のよみこみ
  157.  */
  158. static pix
  159. read_color15( pix bc)
  160. {
  161.     pix    cc;
  162.     long    j,k,m;
  163.  
  164.     k = bc >> 8;
  165.     if ( bit_load( 1) == 0) {
  166.         cache_pos[k] = m = (cache_pos[k] - 1) & (N_CACHE - 1);
  167.         cc = cache[k][m] = bit_load( 15) * 2;
  168.     } else {
  169.         j = bit_load( 6);
  170.         m = cache_pos[k];
  171.         cc = cache[k][(m + j) & (N_CACHE -1 )];
  172.     }
  173.     return ( cc);
  174. }
  175.  
  176. /*
  177.  * 8bit色 よみこみ
  178.  */
  179. static uchar
  180. read_color8( void)
  181. {
  182.     uchar *cache8 = (uchar *)(cache_pos + 256);
  183.     uchar cc;
  184.     long i,n;
  185.     
  186.     if ( bit_load( 1) == 0) {
  187.         /* はずれ */
  188.         
  189.         for ( i = 16; i > 0; i--) {
  190.             cache8[ i] = cache8[ i - 1];
  191.         }
  192.         cache8[ 0] = cc = bit_load( 8);
  193.     } else {
  194.         /* あたり */
  195.         n = bit_load(4);
  196.         cc = cache8[ n];
  197.         for ( i = n; i > 0; i--) {
  198.             cache8[ i] = cache8[ i - 1];
  199.         }
  200.         cache8[0] = cc;
  201.     }
  202.     
  203.     return ( cc);
  204. }
  205.  
  206. /*
  207.  * 8(16)bit色のよみこみ
  208.  */
  209. static pix
  210. read_color16( pix bc)
  211. {
  212.     pix    cc;
  213.     long    i,n,k;
  214.  
  215.     k = bc & 255;
  216.  
  217.     if ( bit_load( 1) == 0) {
  218.         /* はずれ */
  219.         
  220.         cc = read_color8();
  221.         cc = (cc << 8) + read_color8();
  222.  
  223.         for ( i = 16; i > 0; i--) {
  224.             cache[k][i] = cache[k][i - 1];
  225.         }
  226.         cache[k][0] = cc;
  227.     } else {
  228.         /* あたり */
  229.         n = bit_load( 4);
  230.         cc = cache[k][n];
  231.         
  232.         for ( i = n; i > 0; i--) {
  233.             cache[k][i] = cache[k][i - 1];
  234.         }
  235.         cache[k][0] = cc;
  236.     }
  237.     return ( cc);
  238. }
  239.  
  240. #if 0
  241.  
  242. /*
  243.  * 8bit色 よみこみ
  244.  */
  245. static uchar
  246. read_color8( void)
  247. {
  248.     uchar *cache8 = (uchar *)(cache_pos + 256);
  249.     uchar cc;
  250.     
  251.     if ( bit_load( 1) == 0) {
  252.         /* はずれ */
  253.         
  254.         cc = bit_load( 8);
  255.         cache8_pos = (cache8_pos - 1) & 7;
  256.         cache8[ cache8_pos] = cc;
  257.     } else {
  258.         /* あたり */
  259.     
  260.         cc = cache8[( bit_load(3) + cache8_pos) & 7];
  261.     }
  262.     return ( cc);
  263. }
  264.  
  265. /*
  266.  * 8(16)bit色のよみこみ
  267.  */
  268. static pix
  269. read_color16( pix bc)
  270. {
  271.     pix    cc;
  272.     long    j,k,m;
  273.  
  274.     k = bc & 255;
  275.  
  276.     if ( bit_load( 1) == 0) {
  277.         /* はずれ */
  278.         cc = read_color8();
  279.         cc = (cc << 8) + read_color8();
  280.         
  281.         cache_pos[k] = m = (cache_pos[k] - 1) & 31;
  282.         cache[k][m] = cc;
  283.     } else {
  284.         /* あたり */
  285.         j = bit_load( 5);
  286.         m = cache_pos[k];
  287.         cc = cache[k][(m + j) & 31];
  288.     }
  289.     return ( cc);
  290. }
  291. #endif
  292.  
  293.  
  294. /* 構造体アクセスをケチするため */
  295.  
  296. static void
  297. para_out( void)
  298. {
  299.     fbufp = p2->fbufp;
  300.     n_fbuf = p2->n_fbuf;
  301.     bit_buf = p2->bit_buf;
  302.     n_bit_buf = p2->n_bit_buf;
  303.     len = p2->aa;
  304.     len2 = p2->dd;
  305.     read_color = p2->func;
  306.     ynow = p2->ynow;
  307.     cache8_pos = p2->data;
  308.     vram_prev = p2->vram_prev + 4;
  309.     vram_now = p2->vram_now + 4;
  310.     vram_next = p2->vram_next + 4;
  311.     flag_now = p2->flag_now + 4;
  312.     flag_next = p2->flag_next + 4;
  313.     cache = (pix (_HUGE_ *)[N_CACHE])p2->cache;
  314.     cache_pos = p2->cache_pos;
  315. }
  316.  
  317. static void
  318. para_in( void)
  319. {
  320.     void *p;
  321.     
  322.     p2->fbufp = fbufp;
  323.     p2->n_fbuf = n_fbuf;
  324.     p2->bit_buf = bit_buf;
  325.     p2->n_bit_buf = n_bit_buf;
  326.     p2->aa = len;
  327.     p2->dd = len2;
  328.     p2->func = read_color;
  329.     p2->data = cache8_pos;
  330.  
  331.     p = p2->vram_prev;
  332.     p2->vram_prev = p2->vram_now;
  333.     p2->vram_now = p2->vram_next;
  334.     p2->vram_next = p;
  335.  
  336.     p = p2->flag_now;
  337.     p2->flag_now = p2->flag_next;
  338.     p2->flag_next = p;
  339.  
  340.     p2->ynow = ynow;
  341. }
  342.  
  343. /*
  344.  * 行単位の展開
  345.  */
  346. static long
  347. line_expand( P2 *pp2, pix **line)
  348. {
  349.     long ymax;
  350.     long x,xw;
  351.     pix cc;
  352.  
  353.     if ( setjmp( jmp_env) != 0) return ( -1);
  354.  
  355.     p2 = pp2;
  356.     para_out();
  357.  
  358.     ymax = SHORT2short( p2->blk.y_wid) - 1;
  359.     if ( ynow > ymax) return ( -2);
  360.  
  361.     xw = SHORT2short( p2->blk.x_wid);
  362.     if ( SHORT2short( p2->header.depth) == 8) xw = (xw + 1) / 2;
  363.  
  364.     if ( ynow == 0) {
  365.         cache8_pos = 0;
  366.         len2 = 0;
  367.         len = read_len();
  368.         if ( len == 1023) len2 = 1023;
  369.         else if ( len > 1023) {
  370.             len--;
  371.         }
  372.         cc = 0;
  373.     } else {
  374.         if ( SHORT2short( p2->header.depth) == 8) {
  375.             cc = vram_prev[ xw * 2 - 2];
  376.             cc = cc * 256 + vram_prev[ xw * 2 - 1];
  377.         } else {
  378.             cc = vram_prev[ xw - 1];    /* ひとつ前の色 */
  379.         }
  380.     }
  381.     memset( flag_next, 0, xw * sizeof( flag_next[0]));
  382.  
  383.     for ( x = 0; x < xw; x++) {
  384.         char a = flag_now[ x];
  385.  
  386.         if ( len2 > 0) {
  387.             if ( a < 0) { /* on chain ? */
  388.                 cc = vram_now[x];
  389.                 expand_chain( x, cc);
  390.                 if ( --len2 == 0) {
  391.                     len = read_len();
  392.                     if ( len == 1023) len2 = 1023;
  393.                     else if ( len > 1023) {
  394.                         len--;
  395.                     }
  396.                 }
  397.             } else {
  398.                 vram_now[x] = cc;
  399.             }
  400.         } else {
  401.             if ( a < 0) { /* on chain ? */
  402.                 cc = vram_now[x];
  403.                 expand_chain( x, cc);
  404.             } else if ( --len < 0) {
  405.                 cc = vram_now[x] = read_color( cc);
  406.                 expand_chain( x, cc);
  407.                 len = read_len();
  408.                 if ( len == 1023) len2 = 1023;
  409.                 else if ( len > 1023) {
  410.                     len--;
  411.                 }
  412.             } else {
  413.                 vram_now[x] = cc;
  414.             }    
  415.         }
  416.     }
  417.  
  418.     if ( line != NULL) {
  419.         if ( SHORT2short( p2->header.depth) == 8) {
  420.             long i;
  421.             
  422.             for ( i = xw - 1; i >= 0; i--) {
  423.                 ushort c = vram_now[i];
  424.                 vram_now[ i * 2] = c / 256;
  425.                 vram_now[ i * 2 + 1] = c & 255;
  426.             }
  427.         }
  428.         *line = vram_now;
  429.     }
  430.     ynow++;
  431.     para_in();
  432.  
  433.     return ( ynow - 1);
  434. }
  435.  
  436. /*
  437.  * 高速フォーマット展開の初期化
  438.  */
  439. long
  440. p2sf_ld_init( P2 *p2)
  441. {
  442.     long xw;
  443.  
  444.     p2->ynow = 0;
  445.     switch ( SHORT2short( p2->header.depth)) {
  446.     case 24:
  447.         p2->func = read_color24;
  448.         break;
  449.     case 15:
  450.         p2->func = read_color15;
  451.         break;
  452.     case 8:
  453.         p2->func = read_color16;
  454.         break;
  455.     defalut:
  456.         p2errno= p2->errno = P2E_BADFORM;
  457.         return ( -1);
  458.     }
  459.     p2->nextline = line_expand;
  460.     seek_file( p2, p2->blk_pos + SIZE_OF_BLK);
  461.     xw = SHORT2short( p2->blk.x_wid);
  462.  
  463.     memset( p2->cache, 0, sizeof( cache[0]) * 256);
  464.     memset( p2->cache_pos, 0, sizeof( cache_pos[0]) * 8 * 8 * 8);
  465.     memset( p2->flag_now, 0, (xw + 8) * sizeof( flag_now[0]));
  466.     memset( p2->flag_next, 0, (xw + 8) * sizeof( flag_next[0]));
  467.  
  468.     p2->n_bit_buf = 0;
  469.     p2->n_fbuf = 0;
  470.     p2->bit_buf = 0;
  471.  
  472.     return ( 0);
  473. }
  474.  
  475. /* eof */
  476.